import { _decorator, Component, Node, EventTouch, Button, EventHandler } from "cc";
import { proxyMgr } from "./ProxyMgr";

const { ccclass } = _decorator;

/**
 * 代理==>继承此类
 */
@ccclass('ProxyBase')
export class ProxyBase extends Component {
    /** 按钮事件 */
    private _btnClickMap: Map<string, Function> = new Map();

    protected onLoad(): void {
        this._initCtrl()
    }

    /**
     * 初始化控制器,让绑定的控制器默认属性生效
     */
    private _initCtrl() {
        const ctrlMap = proxyMgr.proxyPropertyMetaMap.get(this.constructor.name)
        if (ctrlMap) {
            for (const [key, value] of ctrlMap.entries()) {
                const defaultValue = this[key] || 0;
                this._setCtrl(key);
                // 设置默认值 会自动调用_onCtrl
                this[key] = defaultValue;
            }
        }
    }

    /**
     * 设置控制器注入setter
     * @param key 
     */
    private _setCtrl(key: string) {
        let _value = this[key];
        const getter = () => _value;

        const setter = (newVal: any) => {
            _value = newVal;
            this._onCtrl(key, _value);
        };

        Object.defineProperty(this, key, {
            get: getter,
            set: setter,
            enumerable: true,
            configurable: true,
        });
    }

    /**
     * 控制器响应
     */
    private _onCtrl(ctrlKey: string, ctrlValue: number) {
        const ctrls = proxyMgr.proxyPropertyMetaMap.get(this.constructor.name)?.get(ctrlKey);
        if (ctrls && ctrls.length > 0) {
            for (let i = 0; i < ctrls.length; i++) {
                const propertyKey = ctrls[i].propertyKey
                const p = this[propertyKey];
                if (p) {
                    if (p instanceof Node)
                        p.active = ctrls[i].ctrlValues.indexOf(ctrlValue) !== -1;
                    else if (p instanceof Component)
                        p.node.active = ctrls[i].ctrlValues.indexOf(ctrlValue) !== -1;
                    else
                        console.warn(`${this.constructor.name}---${propertyKey}---不是node或component`)
                }
            }
        }
    }

    /**
     * 按钮事件相应
     * @param event 
     * @param customEventData 
     */
    private _onButtonEvent(event: EventTouch, customEventData: string) {
        const data = JSON.parse(customEventData);
        const callback = this._btnClickMap.get(data?.uid);
        callback && callback(event, data.customData);
    }

    /**
     * 设置按钮点击事件
     * @param btn 
     * @param callback 
     * @param customData 
     */
    public setButtonClick(btn: Button, callback: (event: EventTouch, customData) => void, customData?: any) {
        const handle = new EventHandler()
        handle.target = this.node;
        handle.component = this.constructor.name;
        handle.handler = '_onButtonEvent';
        const data = { uid: btn.node.uuid, customData }
        handle.customEventData = JSON.stringify(data);
        btn.clickEvents.push(handle);
        this._btnClickMap.set(btn.node.uuid, callback);
    }

    /**
     * 清理按钮点击事件
     * @param btn 
     */
    public clearButtonClick(btn: Button) {
        btn.clickEvents = [];
        this._btnClickMap.delete(btn.node.uuid);
    }

    /**
     * 释放资源
     */
    protected onDestroy(): void {
        this._btnClickMap.clear();
    }
}